package com.ourcraft.informationcollectionsystem.utils.authority;

import com.ourcraft.informationcollectionsystem.utils.response.Result;
import com.ourcraft.informationcollectionsystem.utils.response.ResultCode;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 用于权限验证的切面
 *
 * @author Z0136
 * @since 2023/10/31
 */
@Aspect
@Component
@Order(1)
public class AuthorityValidateAspect {

    /**
     * 验证指定token是否具有对应权限码的权限
     *
     * @param token 用户token
     * @param code  权限码
     * @return 是否具有权限
     */
    private boolean validate(String token, AuthorityCode code) {
        // 从token中获得用户权限
        Integer authority = JWTUtils.getAuthorityByToken(token);
        // 返回验证结果
        return code.validate(authority);
    }

    /**
     * 创建切面绑定的注解，用于确定切面位置
     */
    @Pointcut("@within(com.ourcraft.informationcollectionsystem.utils.authority.AuthorityValidator)")
    public void annotatedClass() {
    }

    @Around("annotatedClass()")
    public Object interceptMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {
        // 在进入请求前创建切面，进行权限判断
        Object[] args = joinPoint.getArgs();

        // 权限验证
        // 未通过时返回无权限访问
        if (args.length > 0 && !validate(((HttpServletRequest) args[args.length - 1]).getHeader("Token"),
                joinPoint.getTarget().getClass().getAnnotation(AuthorityValidator.class).code()))
            return Result.fail(ResultCode.UNATUTHORIZED);
        // 通过时返回原请求结果
        return joinPoint.proceed();
    }
}
